package com.pro.framework.spring.util;

import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.type.filter.AssignableTypeFilter;

import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class ClassScanner {
    @SuppressWarnings("unchecked")
//    public static <T> Set<Class<T>> scanClasses(List<String> packageNames) {
//        return scanClasses(packageNames, null);
//    }
    public static <T> Set<Class<T>> scanClasses(Collection<String> packageNames, Class<T> filterSuperClass) {
        ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
        if (filterSuperClass != null) {
            scanner.addIncludeFilter(new AssignableTypeFilter(filterSuperClass));
        }

        Set<Class<T>> classes = new HashSet<>();
        for (String packageName : packageNames) {
            for (BeanDefinition beanDefinition : scanner.findCandidateComponents(packageName)) {
                try {
                    Class<T> clazz = (Class<T>) Class.forName(beanDefinition.getBeanClassName());
                    classes.add(clazz);
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
            }
        }
        return classes;
    }
    public static <T> Set<Class<T>> scanClasses(String packageName, Class<T> filterSuperClass) {
        return scanClasses(List.of(packageName), filterSuperClass);
    }
}
